<template>
  <el-table
    :data="tableData"
    isLoading="isLoading"
    :element-loading-text="elementLoadingText"
    :element-loading-spinner="elementLoadingSpinner"
    :element-loading-background="elementLoadingBackground"
    :element-loading-svg="elementLoadingSvg"
    :element-loading-svg-view-box="elementLoadingSvgViewBox"
    @row-click="rowClick"
    :highlight-current-row="highlightCurrentRow"
    @current-change="CurrentChange"
    @selection-change="handleSelectionChange"
    v-bind="$attrs"
  >
    <el-table-column type="selection" width="55" />
    <template v-for="(item, index) in tableOptions" :key="index">
      <el-table-column
        :label="item.lable"
        :prop="item.prop"
        :align="item.align"
        :width="item.width"
      >
        <template #default="scope">
          <template v-if="scope.row.isEditRow">
            <el-input size="small" v-model="scope.row[item.prop]"></el-input>
          </template>
          <template v-else>
            <template v-if="scope.$index + scope.column.id === currentEdit">
            <div class="icon">
              <el-input
              v-model="scope.row[item.prop!] "
              style="width: 120px"
            ></el-input>
            <div @click="clickEditCell">
              <slot name="editCell" v-if="$slots.editCell"></slot>
              <div v-else>
                <el-icon-check class="check" @click="check(scope)"></el-icon-check>
                <el-icon-close class="close" @click="close(scope)"></el-icon-close>
              </div>
            </div>
            </div>
          </template>
          <template v-else>
            <slot v-if="item.slot" :name="item.slot" :scope="scope"></slot>
            <span v-else>{{ scope.row[item.prop!] }}</span>
            <component :is='`el-icon-${toLine(editIcon!)}`' @click="clickEdit(scope)" v-if="item.editable"></component>
          </template>
          </template>
        </template>
      </el-table-column>
    </template>
    <el-table-column
      :label="actionOptions!.lable"
      :align="actionOptions!.align"
      :width="actionOptions!.width"
    >
      <template #default="scope">
        <slot name="editRow" v-if="scope.row.isEditRow"></slot>
        <slot name="action" :scope="scope" v-else></slot>
      </template>
    </el-table-column>
  </el-table>
  <div class="pagination" v-if="pageination">
    <el-pagination
     :current-page="currentPage"
     :page-size="pageSize"
      :page-sizes="pageSizes"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
  </div>
</template>

<script setup lang="ts">
import { PropType, computed, ref, onMounted, watch } from 'vue';
import { TableOptions } from "./type"
import { toLine } from "../../../utils"
import { cloneDeep } from "lodash"

const props = defineProps({
  //表格的配置tableOptions
  options: {
    type: Array as PropType<TableOptions[]>,
    required: true,
  },
  //表格数据
  data: {
    type: Array as PropType<any[]>,
    required: true,
  },
  //加载的文案
  elementLoadingText: {
    type: String,
  },
  //加载图表名称
  elementLoadingSpinner: {
    type: String,
  },
  //加载背景颜色
  elementLoadingBackground: {
    type: String,
  },
  //加载svg
  elementLoadingSvg: {
    type: String,
  },
  elementLoadingSvgViewBox: {
    type: String,
  },
  //可编辑单元格图标
  editIcon: {
    type: String,
    default: 'edit'
  },
  //是否可以编辑行
  isEditRow: {
    type: Boolean,
    default: false
  },
  //编辑行按钮标识
  editRowIndex: {
    type: String,
    default: ''
  },
  //是否显示分页
  pageination: {
    type:Boolean,
    default: false
  },
  //当前第几页数据
  currentPage: {
    type: Number,
    default: 1,
  },
  pageSizes: {
    type: Array as PropType<number[]>,
    default: [10,20,30,40,50]
  },
  pageSize: {
    type: Number,
    default: 10
  },
  total: {
    type: Number
  },
  //是否可以选择
  highlightCurrentRow: {
    type: Boolean,
    default: false
  }
});
let emits = defineEmits(['comfirm','cancel','update:editRowIndex','sizeChange','currentChange','currentChangeRow','SelectionChange'])
//当前点击的单元格
let currentEdit = ref<string>("");
//拷贝一份当前的表格的数据
let tableData = ref<any[]>(cloneDeep(props.data))
//监听父组件传递过来的数据
watch(() => props.data, val => {
  tableData.value = val
  tableData.value.map(item => {
    item.rowEdit = false
  })
},{deep: true})
watch(() => props.editRowIndex, val => {
  if (val) cloneEditRowIndex.value = val
})
onMounted(() => {
  tableData.value.map(item => {
    //代表当前是否可编辑的状态
    item.rowEdit = false
  })
})
//拷贝一份按钮的标识
let cloneEditRowIndex = ref<any>(props.editRowIndex)
//过滤操作选项之后的配置
let tableOptions = computed(() => props.options.filter((item) => !item.action));
//找出操作项的配置
let actionOptions = computed(() => props.options.find((item) => item.action));
//表格是否在加载中
let isLoading = computed(() => !props.data.length || !props.data);
//点击编辑图标
let clickEdit = (scope: any) => {
  //唯一的标识
  currentEdit.value = scope.$index + scope.column.id;
};
//点击钩
let check = (scope: any) => {
  currentEdit.value = ''
  emits('comfirm',scope)
}
//点击×
let close = (scope: any) => {
  currentEdit.value = ''
  emits('cancel',scope)
}
let clickEditCell = () => {
  currentEdit.value = ''
}
//点击每一行的事件
let rowClick = (row: any, column: any) => {
  //判断当前点击的是否是操作项
  if (column.label === actionOptions.value!.lable){
    //编辑行的操作
    if (props.isEditRow && cloneEditRowIndex.value === props.editRowIndex) {
      //点击的按钮是做可编辑的操作
      row.isEditRow = !row.isEditRow
      //重置其他数据的isEditRow
      tableData.value.map(item => {
        if (item !== row) item.isEditRow = false
      })
      
    }
  }
}
//分页条数改变
let handleSizeChange = (val: number) => {
  emits('sizeChange', val)
}
//分页页数改变
let handleCurrentChange = (val: number) => {
  emits('currentChange',val)
}
const CurrentChange = (val: any) => {
  emits('currentChangeRow',val)
}
const handleSelectionChange = (val: any) => {
  emits('SelectionChange',val)
}
</script>

<style scoped>
svg {
  height: 1em;
  width: 1em;
  position: relative;
  top: 2px;
  left: 10px;
  cursor: pointer;
}
.icon {
  display: flex;
  align-items: center;
  justify-content: center;
}
.check,.close {
  width: 1.5em;
  height: 1.5em;
  margin-left: 5px;
}
.check{
  color: red;
}
.close{
  color: green;
}
.pagination{
  display: flex;
  align-items: center;
  margin-top: 16px;
  justify-content: center;
}
</style>
